const sshConfig = require('ssh-config')
const os = require('os')
const { join } = require('path')
const fs = require('fs-extra')
const cache = require('../../utils/cache.js')
const file = require('../../utils/file.js')
const connection = require('../../utils/connection.js')
const log = require('../../utils/log.js')

async function onInit() {
    const clients = await cache.clients.find()
    const newClients = await discoverClients()
    for (const newClient of newClients) {
        const exists = clients.some(client => client.host == newClient.host)
        if (exists) {
            continue
        }
        clients.push(newClient)
    }
    clients.forEach(it => {
        it.isConnected = cache.connections.has(it.host)
    })
    const root = join(os.homedir(), '.ssh-server')
    const privateKeyPath = join(os.homedir(), '.ssh', 'id_rsa')
    return {
        privateKeyPath,
        root,
        clients,
        platform: os.platform
    }
}

async function discoverClients() {
    const clients = []
    const configPath = join(os.homedir(), '.ssh', 'config')
    const exists = await fs.pathExists(configPath)
    if (!exists) {
        return clients
    }
    const text = await fs.readFile(configPath, {
        encoding: 'utf8'
    })
    const hostList = sshConfig.parse(text)
    hostList.forEach(item => {
        if (item.type == sshConfig.LineType.DIRECTIVE && item.param == 'Host') {
            const details = item.config
            const client = {
                name: item.value
            }
            for (const prop of details) {
                if (prop.type != sshConfig.LineType.DIRECTIVE) {
                    continue
                }
                if (prop.param == 'IdentityFile') {
                    if (prop.value?.startsWith('~')) {
                        client.IdentityFile = join(os.homedir(), prop.value.slice(1))
                    }
                } else {
                    client[prop.param] = prop.value
                }
            }
            clients.push(client)
        }
    })
    const defaultPath = join(os.homedir(), '.ssh', 'id_rsa')
    return clients.map(it => ({
        name: it.name,
        host: it.HostName,
        username: it.User,
        privateKeyPath: it.IdentityFile || defaultPath,
        method: 'key',
        undeletable: true,
        description: configPath
    }))
}

async function onOpenFilePicker() {
    return await file.selectFile('选择私钥文件', '', '私钥地址', [])
}

async function onConnect(data) {
    try {
        this.view.setButtonStatus('连接', ['loading', 'disable'])
        await connection.connect(data)
        this.view.close()
    } catch (error) {
        log.notice.error('连接失败, ' + error.message || '未知异常')
    } finally {
        this.view.setButtonStatus('连接', [])
    }
}

async function onDisconnect(host) {
    await connection.disconnect(host)
    return host
}

async function onRemove(opts) {
    onDisconnect(opts.host)
    await cache.clients.remove(opts)
}

module.exports = {
    onConnect,
    onInit,
    onOpenFilePicker,
    onRemove,
    onDisconnect
}
